package com.lkm.app_ui.ui;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.lkm.app_ui.RunTimeData;
import com.lkm.app_ui.entity.UserVipOrderInfo;
import com.lkm.app_ui.help.GsonHelp;
import com.lkm.javatool.CollectionHelp;
import com.lkm.javatool.NumberHelp;
import com.lkm.javatool.StringHelp;
import com.lkm.market2_0.AppDataCache;
import com.lkm.market2_0.entity.OrganizationInfo;
import com.lkm.market2_0.entity.StallEntity;
import com.lkm.market2_0.entity.SteelyardInfo;
import com.lkm.market2_0.help.SteelardHelp;
import com.lkm.market2_0.m.steelyarddata.OrderEntity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class SalePrint {


    public static void main(String[] args) {


//        Map<String,String> m = GsonHelp.fromJson("{\"k\":\"1\",\"e\":{\"w\":2}}",new TypeToken<Map<String,String>>(){}.getType());

//        System.out.println(m.get("e"));

        JsonObject jsonObject = GsonHelp.fromJson("{\"k\":\"1\",\"e\":{\"w\":2}}", JsonObject.class);

        System.out.println(jsonObject.get("k"));


    }


    private void inserVar(Map<String, String> varDataMap, String preName, Object var) {
        if (var == null) return;

        JsonObject jsonObject = GsonHelp.toJsonObject(var);
        inserVarFoyJsonObject(varDataMap, preName, jsonObject);
    }

    private void inserVarFoyJsonObject(Map<String, String> varDataMap, String preName, JsonObject jsonObject) {
        try {
            for (Map.Entry<String, JsonElement> en : jsonObject.entrySet()) {
                if (en.getValue().isJsonPrimitive())
                    varDataMap.put(preName + en.getKey(), en.getValue().getAsString());

            }
        } catch (Exception e) {
        }
    }

    String template01 = "{\"sp\":\"-\"}\n" +
            "市场：${orgName}\n" +
            "档口号：${stallName}\n" +
            "秤号：${bid}\n" +
            "溯源编码：${orderId}\n" +
            "if(${isSalesReturn})\n" +
            "退货时间：${addTime}\n" +
            "if(!${isSalesReturn})\n" +
            "交易时间：${addTime}\n" +
            "支付方式：${payTypeName}\n" +
            "[Line]${sp}\n" +
            "${goodWeights}\n" +
            "${goodNums}\n" +
            "合计${padding}${allPrice}元\n" +
            "[L_center]${qrStr}\n" +
            "[QR]${qr_url}";

    String template02 = "{\"sp\":\"-\"}\n" +
            "市场：${orgName}\n" +
            "档口号：${stallName}\n" +
            "秤号：${bid}\n" +
            "溯源编码：${orderId}\n" +
            "if(${isSalesReturn})\n" +
            "退货时间：${addTime}\n" +
            "if(!${isSalesReturn})\n" +
            "交易时间：${addTime}\n" +
            "[Line]${sp}\n" +
            "${goodWeights}\n" +
            "${goodNums}\n" +
            "合计${padding}${allPrice}元\n" +
            "[L_center]${qrStr}\n" +
            "[QR]${qr_url}";

    public String cretePrintContent(OrderEntity orderEntity, String allPrice, List<OrderEntity.GoodEntity> goodList, String add_time, SteelyardInfo steelyardInfo, String qr_url) {

        /*二〇二四年六月二十日 19:13:09，由于需要新增打印方式，同时中字内部矛盾原因，无法接口控制修改这个模板，所以决定先写死*/
        //String template = "RunTimeData.orderPrintTemplate";
        String template = (RunTimeData.orderEntity.payTypeName != null && RunTimeData.orderEntity.payTypeName.length() > 0) ? template01 : template02;

        Map<String, String> configDataMap = new HashMap<>();

        boolean hasVip = (RunTimeData.PrintVipOrderInfo != null && !StringHelp.isEmpty(RunTimeData.PrintVipOrderInfo.vip_no));
        if (hasVip) {
            configDataMap.put("goodWeights", printWeightVip(RunTimeData.PrintVipOrderInfo.goods));
        } else {
            configDataMap.put("goodWeights", printWeight(goodList));
            configDataMap.put("goodNums", printNum(goodList));
        }
        configDataMap.put("hasGoodWeights", "" + (!StringHelp.isEmpty(configDataMap.get("goodWeights"))));
        configDataMap.put("hasGoodNums", "" + (!StringHelp.isEmpty(configDataMap.get("goodNums"))));

        OrganizationInfo organizationInfo = AppDataCache.getInstance().getOrganizationEntity(steelyardInfo.getOrg());
        StallEntity      stallEntity      = steelyardInfo.getStallEntity();
        if (organizationInfo != null) {
            inserVar(configDataMap, "org_", organizationInfo);
        }
        inserVar(configDataMap, "oe_", orderEntity);
        inserVar(configDataMap, "si_", steelyardInfo);
        inserVar(configDataMap, "se_", steelyardInfo.getStallEntity());


        configDataMap.put("hasVip", "" + hasVip);
        inserVar(configDataMap, "vip_", RunTimeData.PrintVipOrderInfo);
        if (RunTimeData.PrintVipOrderInfo != null)
            inserVarFoyJsonObject(configDataMap, "vip_", RunTimeData.PrintVipOrderInfo.json);

        // System.out.println("==== vip_totle_amount"+GsonHelp.toJson(configDataMap));

        configDataMap.put("orgName", organizationInfo == null ? "" : organizationInfo.getName());
        configDataMap.put("stallName", stallEntity.getStallName());
        configDataMap.put("name", stallEntity.getName());
        configDataMap.put("phone", stallEntity.getPhone());
        configDataMap.put("bid", steelyardInfo.getB_id());
        configDataMap.put("payTypeName", orderEntity.payTypeName);
        configDataMap.put("orderId", orderEntity.orderNum);
        configDataMap.put("addTime", add_time);
        System.out.println("Bill->Print->orderEntity.payTypeName：" + orderEntity.payTypeName);
        System.out.println("Bill->Print->RunTimeData.orderEntity：" + RunTimeData.orderEntity.payTypeName);
        configDataMap.put("allPrice", allPrice);


        configDataMap.put("oe_payment_amount", StringHelp.getNotEmpty(orderEntity.payment_amount, allPrice));

        configDataMap.put("qrStr", StringHelp.getNotEmpty(steelyardInfo.codetext, "扫描二维码查看溯源信息"));
        configDataMap.put("isSalesReturn", "" + orderEntity.isSalesReturn());
        configDataMap.put("qr_url", qr_url);


        configDataMap.put("padding", "#lkm#_padding");


        try {
            String line = new BufferedReader(new StringReader(template)).readLine();

            if (line.startsWith("{")) {
                template = template.substring(line.length() + 1);
            }
            HashMap<String, String> vmap = GsonHelp.fromJson(line, new com.google.gson.reflect.TypeToken<HashMap<String, String>>() {
            }.getType());
            inserVar(configDataMap, "", vmap);

        } catch (Exception e) {
            e.printStackTrace();
        }


        String orderSourStr = handle(template, configDataMap);


        BufferedReader bufferedReader = new BufferedReader(new StringReader(orderSourStr));

        StringBuilder orderStringBuilder = new StringBuilder();

        String cmd    = null;
        String precmd = null;
        while (true) {
            precmd = cmd;
            cmd = null;
            String line = null;
            try {
                line = bufferedReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (line == null) break;


            if (line.contains("#lkm#")) {
                if (line.contains("#lkm#_padding")) {
                    int lineLength = getCharWidth(line.replaceAll("#lkm#_padding", ""));
                    line = line.replaceAll("#lkm#_padding", getSpaceChars(32 - lineLength));
                }
            }

            if (line.startsWith("if(")) {

                if (line.equals("if(!true)") || line.equals("if(false)")) {

                    cmd = "deleteLine";
                    continue;
                }
                if (line.equals("if(!false)") || line.equals("if(true)")) {

                    cmd = null;
                    continue;
                }

            } else if (line.startsWith("[L_center]")) {
                line = holdLineCenter(line.substring(10));
            } else if (line.startsWith("[Line]")) {

                line = getChars(32, line.substring(6));

            } else if (line.startsWith("[QR]")) {

                continue;
            } else {
                line = holdLine(line);
            }


            if (precmd != null && precmd.equals("deleteLine")) {

                cmd = null;
                continue;
            }

            orderStringBuilder.append(line);

        }

        return orderStringBuilder.toString();
    }

    private static String handle(String template, Map<String, String> varDataMap) {


        String sourceStr = template;


        List<String> keys = new LinkedList<String>();


        {
            Set<String> varTemps = new HashSet<String>();
            Pattern mPattern = Pattern.compile("\\$\\{\\s*([^}]+)\\s*\\}",
                    Pattern.CASE_INSENSITIVE);
            Matcher mMatcher = mPattern.matcher(sourceStr);
            while (mMatcher.find()) {
                String key = mMatcher.group(1).trim();
                varTemps.add(key);
            }


            for (Iterator<String> iterator = varTemps.iterator(); iterator.hasNext(); ) {
                keys.add((String) iterator.next());
            }
        }
        String  outStr = sourceStr;
        boolean isTH   = false;
        for (String key : keys) {
            String ckey = key.replaceAll("[.]", "\\\\.");
//			System.out.println(ckey);
            String value = varDataMap.get(key);
            if (value == null) value = "";
            if (value != null) {
                isTH = true;
                outStr = outStr.replaceAll("\\$\\{\\s*" + ckey + "\\s*\\}", value);
            }
        }


        return outStr;


    }


    private String printNum(List<OrderEntity.GoodEntity> goodList_) {
        List<OrderEntity.GoodEntity> goodList = new ArrayList<>();
        if (goodList_ != null)
            for (int i = 0; i < goodList_.size(); i++) {
                OrderEntity.GoodEntity good = goodList_.get(i);
                if (good.unitType == 2) {
                    goodList.add(good);
                }
            }
        if (CollectionHelp.isEmpty(goodList)) {
            return "";
        }

        String goodTable = "";
        goodTable += holdLine(" 名称?单价?数量?金额".replaceAll("[?]", "     "));


        goodTable += holdLine("  ?(元/件)?(件)?(元)".replaceAll("[?]", "     "));

        for (int i = 0; i < goodList.size(); i++) {

            OrderEntity.GoodEntity good = goodList.get(i);
            if (good.unitType != 2) {
                continue;
            }

            String itemStr = "";
            String name    = StringHelp.isEmpty(good.goodName) ? "商品" : good.goodName;
            if (name.length() > 4)
                name = name.substring(0, 4);
            itemStr += name + (getSpaceChars(8 - getCharWidth(name)));

            String price = SteelardHelp.formatMoney(good.unitPrice);// doubleScaleToString(good.unitPrice ,2, BigDecimal.ROUND_HALF_DOWN);// ""+String .format("%.2f",good.getUnitPrice());;
            itemStr += (getSpaceChars(7 - getCharWidth(price))) + price + " ";

            String weight = NumberHelp.formatMoney(good.weight, 2);//NumberHelp.doubleScaleToString(good.weight,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(7 - getCharWidth(weight))) + weight + " ";
//            good.unitPrice*good.weight
            String totalPrice = SteelardHelp.formatMoney(good.calPrice());//NumberHelp.doubleScaleToString(good.unitPrice*good.weight ,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(8 - getCharWidth(totalPrice))) + totalPrice;

            if (StringHelp.isEmpty(good.goodCode)) {

            } else {
                itemStr += holdLine("编码：" + good.goodCode);
            }

            if (StringHelp.isEmpty(good.address)) {

            } else {
                itemStr += holdLine("产地：" + good.address);
            }
            if (!StringHelp.isEmpty(good.checkResult)) {
                itemStr += holdLine(good.checkResult);
            }


            goodTable += holdLine(itemStr);
        }
        return goodTable;
    }


    private String printWeight(List<OrderEntity.GoodEntity> goodList_) {

        List<OrderEntity.GoodEntity> goodList = new ArrayList<>();
        if (goodList_ != null)
            for (int i = 0; i < goodList_.size(); i++) {
                OrderEntity.GoodEntity good = goodList_.get(i);
                if (good.unitType == 1) {
                    goodList.add(good);
                }
            }
        if (CollectionHelp.isEmpty(goodList)) {
            return "";
        }

        String goodTable = "";
        goodTable += holdLine(" 名称?单价?重量?金额".replaceAll("[?]", "     "));

        String wunit = RunTimeData.getAppWeightUnit();
        String pTemp = ("??(元/" + wunit + ")?(" + wunit + ")?(元)");
        goodTable += holdLine(pTemp.replaceAll("[?]", getSpaceChars((32 - getCharWidth(pTemp) + 4) / 4)));

        for (int i = 0; i < goodList.size(); i++) {

            OrderEntity.GoodEntity good = goodList.get(i);
            if (good.unitType != 1) {
                continue;
            }

            String itemStr = "";
            String name    = StringHelp.isEmpty(good.goodName) ? "商品" : good.goodName;
            if (name.length() > 4)
                name = name.substring(0, 4);
            itemStr += name + (getSpaceChars(8 - getCharWidth(name)));

            String price = SteelardHelp.formatMoney(good.unitPrice);// doubleScaleToString(good.unitPrice ,2, BigDecimal.ROUND_HALF_DOWN);// ""+String .format("%.2f",good.getUnitPrice());;
            itemStr += (getSpaceChars(7 - getCharWidth(price))) + price + " ";

            String weight = NumberHelp.formatMoney(good.weight, 3);//NumberHelp.doubleScaleToString(good.weight,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(7 - getCharWidth(weight))) + weight + " ";

//            good.unitPrice*good.weight
            String totalPrice = SteelardHelp.formatMoney(good.calPrice());//NumberHelp.doubleScaleToString(good.unitPrice*good.weight ,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(8 - getCharWidth(totalPrice))) + totalPrice;

            if (StringHelp.isEmpty(good.goodCode)) {

            } else {
                itemStr += holdLine("编码：" + good.goodCode);
            }

            if (StringHelp.isEmpty(good.address)) {

            } else {
                itemStr += holdLine("产地：" + good.address);
            }
            if (!StringHelp.isEmpty(good.checkResult)) {
                itemStr += holdLine(good.checkResult);
            }


            goodTable += holdLine(itemStr);
        }
        return goodTable;
    }


    private String printWeightVip(List<UserVipOrderInfo.Goods> goodList) {


        if (CollectionHelp.isEmpty(goodList)) {
            return "";
        }

        String goodTable = "";
        goodTable += holdLine(" 名称?单价?重量?金额".replaceAll("[?]", "     "));

        String wunit = RunTimeData.getAppWeightUnit();
        String pTemp = ("??(元/" + wunit + ")?(" + wunit + ")?(元)");
        goodTable += holdLine(pTemp.replaceAll("[?]", getSpaceChars((32 - getCharWidth(pTemp) + 4) / 4)));

        for (int i = 0; i < goodList.size(); i++) {

            UserVipOrderInfo.Goods good = goodList.get(i);

            String itemStr = "";
            String name    = StringHelp.isEmpty(good.name) ? "商品" : good.name;
            if (name.length() > 4)
                name = name.substring(0, 4);
            itemStr += name + (getSpaceChars(8 - getCharWidth(name)));

            String price = SteelardHelp.formatMoney(good.unitPrice);// doubleScaleToString(good.unitPrice ,2, BigDecimal.ROUND_HALF_DOWN);// ""+String .format("%.2f",good.getUnitPrice());;
            itemStr += (getSpaceChars(7 - getCharWidth(price))) + price + " ";

            String weight = NumberHelp.formatMoney(good.weight, 3);//NumberHelp.doubleScaleToString(good.weight,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(7 - getCharWidth(weight))) + weight + " ";

//            good.unitPrice*good.weight
            String totalPrice = SteelardHelp.formatMoney(good.totalPrice);//NumberHelp.doubleScaleToString(good.unitPrice*good.weight ,2,BigDecimal.ROUND_HALF_DOWN);
            itemStr += (getSpaceChars(8 - getCharWidth(totalPrice))) + totalPrice;

            goodTable += holdLine(itemStr);
        }
        return goodTable;
    }


    public static String holdLine(String s) {


        int sSize = getCharWidth(s);
        if (sSize == 0) {
            return s + getSpaceChars(32);
        }

        return s + getSpaceChars((sSize % 32) == 0 ? 0 : (32 - (sSize % 32)));
    }


    public static String holdLineCenter(String s) {
        float rl = (32 - (getCharWidth(s) % 32)) / 2.0f;

        return holdLine(getSpaceChars((int) Math.ceil(rl)) + s + getSpaceChars((int) Math.floor(rl)));
    }


    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }


    public static int getCharWidth(String strName) {
        int    charWidth = 0;
        char[] ch        = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                charWidth += 2;
            } else {
                charWidth += 1;
            }
        }
        return charWidth;
    }

    public static String getSpaceChars(int num) {
        String sc = "";
        for (int i = 0; i < num; i++) {
            sc += " ";
        }
        return sc;
    }

    public static String getChars(int num, String ct) {
        String sc = "";
        for (int i = 0; i < num; i++) {
            sc += ct;
        }
        return sc;
    }
}
